﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Threading;
using System.Security.Permissions;



namespace System.Collections.Generic.Sync
{

  public   class SyncDictionary<TKey, TValue> : Dictionary<TKey, TValue> ,ICloneable
    {

      public SyncDictionary():base(){}

      public SyncDictionary(int capacity) : base(capacity) { }

      public SyncDictionary(IEqualityComparer <TKey > comparer) : base( comparer ) { }
      public SyncDictionary(int capacity, IEqualityComparer<TKey> comparer) : base(capacity,comparer) { }


      public SyncDictionary(IDictionary<TKey, TValue> dictionary) : base(dictionary) { }

      public SyncDictionary(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info,context ) { }

     

      public SyncDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer) : base(dictionary, comparer) { }


        private ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();

        public new void Add(TKey key, TValue value)
        {
            _lock.EnterWriteLock();
            base.Add(key, value);
            _lock.ExitWriteLock();

        }

        public new void Clear()
        {
            _lock.EnterWriteLock();
            base.Clear();
            _lock.ExitWriteLock();

        }
        public new bool ContainsKey(TKey key)
        {
            _lock.EnterReadLock();
            var rv = base.ContainsKey(key);
            _lock.ExitReadLock();
            return rv;
        }



        public new bool ContainsValue(TValue value)
        {
            _lock.EnterReadLock();
            var rv = base.ContainsValue(value);
            _lock.ExitReadLock();
            return rv;
        }


        public new Dictionary<TKey, TValue>.Enumerator GetEnumerator()
        {
            _lock.EnterReadLock();
            var rv = new Dictionary<TKey, TValue>(this).GetEnumerator();
            _lock.ExitReadLock();
            return rv;
        }
        public new bool Remove(TKey key)
        {
            _lock.EnterWriteLock();
            var rv = base.Remove(key);
            _lock.ExitWriteLock();
            return rv;

        }
        public new bool TryGetValue(TKey key, out TValue value)
        {
            _lock.EnterReadLock();
            var rv = base.TryGetValue(key, out value);
            _lock.ExitReadLock();
            return rv;

        }


        public new int Count
        {
            get
            {
                _lock.EnterReadLock();
                var rv = base.Count;
                _lock.ExitReadLock();
                return rv;
            }

        }


        public new TValue this[TKey key]
        {
            get
            {
                _lock.EnterReadLock();
                var rv = base[key];
                _lock.ExitReadLock();
                return rv;
            }
            set
            {
                _lock.EnterWriteLock();
                base[key] = value;
                _lock.ExitWriteLock();
       
            }
        }


        public  new Generic.Dictionary <TKey, TValue>.KeyCollection Keys
        {
            get
            {

                _lock.EnterReadLock();
                var rv = new KeyCollection( this);
                _lock.ExitReadLock();
                return rv;
            }

        }

        public new Generic.Dictionary<TKey, TValue>.ValueCollection Values
        {
            get
            {
                _lock.EnterReadLock();
                var rv = new ValueCollection (this);
                _lock.ExitReadLock();
                return rv;
            }


   
        }
 
 public  SyncDictionary<TKey, TValue> GetDeepCopy  ()
  {
      return (SyncDictionary<TKey, TValue>)Clone();
  }




    
#region ICloneable Members

public object  Clone()
{
 	return MemberwiseClone ();
}

#endregion
}
}
